/**
 * 
 */
package storage;

import general.Flag;
import general.Status;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;

/**
 * Class that realised all storage functions just in memory
 * 
 * @author Last G
 * 
 */
public class Memory implements StorageAdapter
{

	private static Map<Integer, Flag> mem = new HashMap<Integer, Flag>();
	private static Map<String, Integer> flagToId = new HashMap<String, Integer>();
	
	@SuppressWarnings("unused")
	private Properties config;

	/**
	 * @param config
	 *            стандартный конструктор получающий конфигурации
	 */
	public Memory(Properties config)
	{
		super();
		this.config = config;
	}

	// FIXME убрать костыли
	@Override
	public Flag getFlag(int id) throws StorageException
	{
		if (id < mem.size())
		{
			return mem.get(id);
		}
		return null;
	}

	@Override
	public Flag[] getFlags(Status state, int limit) throws StorageException
	{
		LinkedList<Flag> tmp = new LinkedList<Flag>();
		for (Flag fl : mem.values())
		{
			if (fl.getStatus().equals(state))
			{
				tmp.add(fl);
				if (tmp.size() == limit)
				{
					break;
				}
			}
		}
		return tmp.toArray(new Flag[0]);
	}

	@Override
	public int putFlag(Flag fl) throws StorageException
	{
		synchronized (mem)
		{
			if(flagToId.containsKey(fl.getFlag()))
			{
				return flagToId.get(fl.getFlag());
			}
			flagToId.put(fl.getFlag(), mem.size());
			mem.put(mem.size(), fl);
			return mem.size() - 1;
		}
	}

	@Override
	public void updateStatus(Flag[] flags, Status[] statuses)
			throws StorageException
	{
		synchronized (mem)
		{
			for (int i = 0; i < flags.length && i < statuses.length; ++i)
			{
				flags[i].setStatus(statuses[i]);
			}
		}

	}

	// FIXME Убрать костыли
	@Override
	public Flag getFlagAndLock(int id) throws StorageException
	{
		synchronized (mem)
		{
			Flag result = mem.get(id);
			result.setStatus(Status.Busy);
			return result;
		}
	}

	@Override
	public Flag[] getFlagsAndLock(Status state, int limit)
			throws StorageException
	{
		LinkedList<Flag> tmp = new LinkedList<Flag>();
		synchronized (mem)
		{
			for (Flag fl : mem.values())
			{
				if (fl.getStatus().equals(state))
				{
					fl.setStatus(Status.Busy);
					tmp.add(fl);
				}
				if (tmp.size() >= limit)
				{
					break;
				}
			}
		}
		return tmp.toArray(new Flag[0]);
	}

	@Override
	public void flushDB() throws StorageException
	{
		mem = new HashMap<Integer, Flag>();
		flagToId = new HashMap<String, Integer>();
	}

}
